import pymongo
from pymongo import MongoClient
from dvadmin.utils.sqlprocess import  dict_int_change
from .OnlineHandler import OnlineHandler
from jinjasql import JinjaSql
from ..models import Datasource
import ujson as ujson
from bson import json_util
import re,json

class MongodbSource:
    def __init__(self):
        self.conn_list = {}

    def connect(self,name, host, port, user, password, database):
        client = MongoClient(host='mongodb://{}:{}/'.format(host,port),
                             maxPoolSize=50,
                             serverSelectionTimeoutMS=2000)
        db = client[database]

        # 身份验证
        authenticated = db.authenticate(user, password, source=database)

        if authenticated:
            self.conn_list[name] = db
        else:
            pass

    def testconnect(self,host, port, user, password, database):
        try:
            client = MongoClient(host='mongodb://{}:{}/'.format(host, port))
            db = client[database]
            # 身份验证
            authenticated = db.authenticate(user, password, source=database)
            if authenticated:
                db.client.close()
                return True,None
            else:
                return False, '无效的账号密码'
        except Exception as e:
            return False,e

    def cursor(self,name):
        if name in self.conn_list.keys():
            return self.conn_list[name]
        return

mongodbInit = MongodbSource()

class MongodbHandel(OnlineHandler):
    def __init__(self, obj, requestdata, id, test):
        self.obj = obj
        self.requestdata = requestdata
        self.userid = id
        self.query = None
        self.bind_params = None
        self.newQuery = None
        self.table_name = None
        self.curor = None
        self.test = test
        self.j = JinjaSql()

    def sqlprocess(self):
        self.newQuery = dict_int_change(self.obj['parameter'], self.requestdata, self.userid)
        self.query, self.bind_params = self.j.prepare_query(self.obj['sql'], self.newQuery)
        self.table_name = self.newQuery.get("table_name")


    def createCursor(self):
        conn = mongodbInit.cursor(self.obj['datasource'])
        if conn:
            self.cursor = conn.spider_datas
            return
        obj = Datasource.objects.get(id= self.obj['datasource'])

        mongodbInit.connect(obj.id,obj.host,obj.port,obj.user,obj.password,obj.database)
        self.cursor = mongodbInit.cursor(self.obj['datasource']).spider_datas


    def process(self):
        """
        datatyped： 2-翻页数据
        """
        if self.obj['datatyped'] == 2:
            page = 1
            _limit = 10
            if self.newQuery.get("page"):
                page = int(self.newQuery["page"])
            if self.newQuery.get("limit"):
                _limit = int(self.newQuery["limit"])
            offset = (page - 1) * _limit if page >= 0 else 0

            coll_data, cols_name, total = self.parse_data()
            coll_data = coll_data.limit(_limit).skip(offset)
            return {"data": list(coll_data), 'total': total, 'cols_name': cols_name}

        coll_data, cols_name, _ = self.parse_data()
        if self.obj['datatyped'] == 0:
            return {"data": list(coll_data), 'cols_name': cols_name}
        elif self.obj['datatyped'] == 1:
            return {"data": list(coll_data), 'cols_name': cols_name}

    def parse_data(self):
        query = self.query % tuple(self.bind_params)
        _query = query.replace('\n\n', "").replace('\n', "")
        try:
            _query = json_util.loads(_query)
        except json.decoder.JSONDecodeError:
            _query = ','.join(re.split(r',', _query)[:-1]) + "}"
            _query = json_util.loads(_query)
        projection = ujson.loads(self.newQuery.get('projection'))
        cols_name = [key for key, _ in projection.items() if key not in ["_id"]]
        coll_data = self.db[self.table_name].find(_query, projection)
        total = self.db[self.table_name].count_documents(_query)
        return coll_data, cols_name, total
